package com.hy.activiti.controller;

import com.hy.activiti.service.IProcessDefinitionService;
import com.hy.framework.aspectj.lang.annotation.Log;
import com.hy.framework.aspectj.lang.enums.BusinessType;
import com.hy.framework.web.controller.BaseController;
import com.hy.framework.web.domain.AjaxResult;
import com.hy.framework.web.page.PageDomain;
import com.hy.framework.web.page.TableDataInfo;
import com.hy.framework.web.page.TableSupport;
import com.hy.project.activiti.domain.dto.ProcessDefinitionDTO;
import org.activiti.engine.repository.Model;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;

/**
 * 汇讯数码科技(深圳)有限公司
 * 创建日期:2020/10/22-15:16
 * 版本   开发者     日期
 * 1.0    Danny    2020/10/22
 */
@Controller
@RequestMapping("/activiti/definition")
public class ProcessDefinitionController extends BaseController {
    private String prefix = "activiti/definition";

    @Autowired
    private IProcessDefinitionService processDefinitionService;


    @RequiresPermissions("activiti:definition:view")
    @GetMapping()
    public String definition()
    {
        return prefix + "/definition";
    }

    /**
     * 获取流程定义集合
     *
     * @param processDefinition
     * @return
     */
    @RequiresPermissions("activiti:definition:view")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(ProcessDefinitionDTO processDefinition) {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        return getDataTable(processDefinitionService.selectProcessDefinitionList(processDefinition, pageDomain));

    }

    /**
     * 流程模型列表
     *
     * @param processDefinition
     * @return
     */
    @RequiresPermissions("activiti:model:view")
    @PostMapping("/modelList")
    @ResponseBody
    public TableDataInfo modelList(Model model) {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        return getDataTable(processDefinitionService.selectModelList(model, pageDomain));
    }

    /**
     * 运行中的实例列表
     */
    @RequiresPermissions("activiti:definition:edit")
    @RequestMapping(value = "running")
    public TableDataInfo runningList(ProcessInstance processInstance) {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        return getDataTable(processDefinitionService.selectProcessRunningList(processInstance, pageDomain));
    }


    /**
     * 读取资源，通过部署ID
     * @param processDefinitionId  流程定义ID
     * @param processInstanceId 流程实例ID
     * @param resourceType 资源类型(xml|image)
     * @param response
     * @throws Exception
     */
    @RequiresPermissions("activiti:definition:view")
    @RequestMapping(value = "resource/read/{procDefId}/{resType}")
    public void resourceRead(@PathVariable("procDefId") String procDefId
            ,@PathVariable("resType") String resType, HttpServletResponse response) throws Exception {
        InputStream resourceAsStream = processDefinitionService.resourceRead(procDefId, "", resType);
        byte[] b = new byte[1024];
        int len = -1;
        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }
    }


    /**
     *
     * @return
     */
    @GetMapping(value = "/getDefinitions/{instanceId}")
    public AjaxResult getDefinitionsByInstanceId(@PathVariable("instanceId") String instanceId){
        return AjaxResult.success(processDefinitionService.getDefinitionsByInstanceId(instanceId));
    }

    /**
     * 删除流程定义
     *
     * @param deploymentId
     * @return
     */
    @Log(title = "流程定义管理", businessType = BusinessType.DELETE)
    @DeleteMapping(value = "/remove/{deploymentId}")
    public AjaxResult delDefinition(@PathVariable("deploymentId") String deploymentId) {
        return toAjax(processDefinitionService.deleteProcessDefinitionById(deploymentId));
    }

    /**
     * 上传并部署流程定义
     *
     * @param file
     * @return
     * @throws IOException
     */
    @Log(title = "流程定义管理", businessType = BusinessType.IMPORT)
    @PostMapping(value = "/uploadStreamAndDeployment")
    public AjaxResult uploadStreamAndDeployment(@RequestParam("file") MultipartFile file) throws IOException {
        processDefinitionService.uploadStreamAndDeployment(file);
        return AjaxResult.success();
    }

    /**
     * 启动挂起流程流程定义
     *
     * @param processDefinition
     * @return
     */
    @Log(title = "流程定义管理", businessType = BusinessType.UPDATE)
    @PostMapping("/suspendOrActiveApply")
    @ResponseBody
    public AjaxResult suspendOrActiveApply(@RequestBody ProcessDefinitionDTO processDefinition) {
        processDefinitionService.suspendOrActiveApply(processDefinition.getId(), processDefinition.getSuspendState());
        return AjaxResult.success();
    }

    /**
     * 上传流程流程定义
     *
     * @param multipartFile
     * @return
     * @throws IOException
     */
    @Log(title = "流程定义管理", businessType = BusinessType.IMPORT)
    @PostMapping(value = "/upload")
    public AjaxResult upload(@RequestParam("processFile") MultipartFile multipartFile) throws IOException {

        if (!multipartFile.isEmpty()) {
            String fileName = processDefinitionService.upload(multipartFile);
            return AjaxResult.success("操作成功", fileName);

        }
        return AjaxResult.error("不允许上传空文件！");
    }


    /**
     * 通过stringBPMN添加流程定义
     *
     * @param stringBPMN
     * @return
     */
    @PostMapping(value = "/addDeploymentByString")
    public AjaxResult addDeploymentByString(@RequestParam("stringBPMN") String stringBPMN) {
        processDefinitionService.addDeploymentByString(stringBPMN);
        return AjaxResult.success();

    }


    /**
     * 获取流程定义XML
     *
     * @param response
     * @param deploymentId
     * @param resourceName
     */
    @GetMapping(value = "/getDefinitionXML")
    public void getProcessDefineXML(HttpServletResponse response,
                                    @RequestParam("deploymentId") String deploymentId,
                                    @RequestParam("resourceName") String resourceName) throws IOException {

        processDefinitionService.getProcessDefineXML(response, deploymentId, resourceName);
    }

    //模型开始
    /**
     * 创建模型
     */
    @RequiresPermissions("act:model:edit")
    @RequestMapping(value = "create", method = RequestMethod.POST)
    public void create(String name, String key, String description, String category,
                       HttpServletRequest request, HttpServletResponse response) {
        try {
            org.activiti.engine.repository.Model modelData = processDefinitionService.create(name, key, description, category);
            response.sendRedirect(request.getContextPath() + "/act/rest/service/editor?id=" + modelData.getId());
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("创建模型失败：", e);
        }
    }

    /**
     * 根据Model部署流程
     */

    @RequiresPermissions("act:model:edit")
    @RequestMapping(value = "deploy")
    public AjaxResult deploy(String id) {
        String message = processDefinitionService.deploy(id);
        return AjaxResult.success(message);
    }

    /**
     * 导出model的xml文件
     */
    @RequiresPermissions("act:model:edit")
    @RequestMapping(value = "export")
    public void export(String id, HttpServletResponse response) {
        processDefinitionService.exportModelById(response ,id);
    }

    /**
     * 更新Model分类
     */
    @RequiresPermissions("act:model:edit")
    @RequestMapping(value = "updateCategory")
    public String updateCategory(String id, String category) {
        /*
        actModelService.updateCategory(id, category);
        redirectAttributes.addFlashAttribute("message", "设置成功，模块ID=" + id);
        return "redirect:" + adminPath + "/act/model";
        */
        return "";
    }

    /**
     * 删除Model
     * @param id
     * @param redirectAttributes
     * @return
     */
    @RequiresPermissions("act:model:edit")
    @RequestMapping(value = "deleteModel")
    public AjaxResult deleteModel(@PathVariable("modelId") String modelId) {
        return toAjax(processDefinitionService.deleteModelById(modelId));
    }


    //模型结束


}
